﻿using System;
using System.Windows;
using GpgApi;
using Microsoft.Win32;
using WgpgCore;

namespace WgpgGUI
{
    public static class Decrypt
    {
        public static void File(Window owner, String filename)
        {
            if (String.IsNullOrEmpty(filename))
            {
                OpenFileDialog dialog = new OpenFileDialog
                {
                    Title = L10N.T("select_encrypted_file"),
                    Multiselect = false,
                    CheckFileExists = true,
                    CheckPathExists = true,
                    Filter = L10N.T("filter_allfiles") + "|*.*"
                };

                if (dialog.ShowDialog(owner) != true)
                    return;

                filename = dialog.FileName;
            }

            String temp_filename = Utils.GetTempFileName();

            GpgDecrypt decrypt = new GpgDecrypt(filename, temp_filename)
            {
                AskPassphrase = GUIUtils.AskPassphrase(owner)
            };

            TaskManager.Instance.Add(decrypt, "Decrypt " + filename);

            decrypt.ExecuteAsync(result =>
            {
                try
                {
                    if (result.Status == GpgInterfaceStatus.Error)
                    {
                        if (result.Message == GpgInterfaceMessage.BadPassphrase)
                        {
                            CustomMessageBox.Show(owner, L10N.T("bad_passphrase"), L10N.T("bad_passphrase_title"), MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
                            return;
                        }

                        String message = String.Empty;

                        switch (result.Message)
                        {
                            case GpgInterfaceMessage.DataError:
                                message = L10N.T("decryption_nodata_file");
                                break;

                            case GpgInterfaceMessage.NoSecretKey:
                                message = L10N.T("decryption_no_secret_key_file");
                                break;

                            case GpgInterfaceMessage.NoPublicKey:
                                message = L10N.T("verify_signature_no_public_key");
                                break;

                            case GpgInterfaceMessage.DecryptionFailed:
                                message = L10N.T("decryption_error_file");
                                break;
                        }

                        CustomMessageBox.Show(owner, message, L10N.T("decryption_file_error_title"), MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
                        return;
                    }

                    if (result.Status == GpgInterfaceStatus.Success)
                    {
                        String message = "The decryption of <Bold>" + decrypt.EncryptedFileName + "</Bold> has succeded.\n\n";

                        if (decrypt.IsSigned)
                        {
                            message += "This file was signed by <Bold>" + decrypt.SignatureKeyId + "</Bold> on " + decrypt.SignatureDateTime + "\n";
                            message += "The signature is <Bold>" + (decrypt.IsGoodSignature ? "valid" : "NOT valid") + "</Bold>\n";
                            message += "Signature trust: <Bold>" + decrypt.SignatureTrust + "</Bold>\n\n";
                        }

                        if (!String.IsNullOrEmpty(decrypt.OriginalFileName))
                            message += "The original filename was <Bold>" + decrypt.OriginalFileName + "</Bold>, ";
                        message += "it was encrypted on <Bold>" + decrypt.EncryptionDateTime + "</Bold>";

                        String type = String.Empty;
                        switch (decrypt.DecryptedDataType)
                        {
                            case DataType.None:
                            case DataType.Binary:
                                type = "binary";
                                break;
                            case DataType.Text:
                            case DataType.Utf8Text:
                                type = "text";
                                break;
                        }

                        message += " and it is a <Bold>" + type + "</Bold> content.\n\n";
                        message += "What would you like to do with this content?";

                        MessageBoxResult box = CustomMessageBox.Show(owner, message, "Decrypt File - Success", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Yes, "Save to file", null, null, "Cancel", MessageBoxResult.Cancel);

                        if (box == MessageBoxResult.Cancel)
                            return;

                        if (box == MessageBoxResult.OK)    // Save to file
                        {
                            SaveFileDialog savedialog = new SaveFileDialog
                            {
                                Title = "Save to file",
                                FileName = decrypt.OriginalFileName,
                                Filter = L10N.T("filter_allfiles") + "|*.*"
                            };

                            if (savedialog.ShowDialog(owner) == false)
                                return;

                            System.IO.File.Move(temp_filename, savedialog.FileName);
                        }
                    }
                }
                finally
                {
                    if (!String.IsNullOrEmpty(temp_filename))
                        System.IO.File.Delete(temp_filename);
                    temp_filename = null;
                }
            });
        }
    }
}
